package com.onLineCar.vehicle.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.onLineCar.common.core.domain.Result;
import com.onLineCar.common.core.utils.StringUtils;
import com.onLineCar.vehicle.entity.TblOrder;
import com.onLineCar.vehicle.entity.request.Reconciliation;
import com.onLineCar.vehicle.entity.request.ReqDriverPreemptOrder;
import com.onLineCar.vehicle.entity.request.RequestUpdate;
import com.onLineCar.vehicle.entity.request.TblOrderRequest;
import com.onLineCar.vehicle.entity.request.driver.DriverOrderRequest;
import com.onLineCar.vehicle.entity.request.user.UserOrderRequest;
import com.onLineCar.vehicle.service.ITblOrderService;
import lombok.extern.log4j.Log4j2;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.util.List;


/**
 *
 * 订单表 前端控制器
 *
 *
 * @author Xinke_Li
 * @since 2023-12-11
 */
@RestController
@RequestMapping("/tbl-order")
@Log4j2
public class TblOrderController {
    private final ITblOrderService iTblOrderService;

    private final HttpServletRequest  request;


    public TblOrderController(ITblOrderService iTblOrderService, HttpServletRequest request) {
        this.iTblOrderService = iTblOrderService;
        this.request = request;
    }

    /**
     * @description: 生成订单编号
     * @author: Lxk
     * @date: 2023/12/27 18:35
     * @param: []
     * @return: java.lang.String
     **/
    @GetMapping("/createAnOrderNumber")
    public String createAnOrderNumber() {
        return iTblOrderService.createAnOrderNumber();
    }

    /**
     * @description: 订单列表
     * @author: Lxk
     * @date: 2023/12/12 10:31
     * @param: [tblOrderRequest]
     * @return: com.onLineCar.common.core.domain.Result<java.util.List<com.onLine.vehicle.entity.TblOrder>>
     **/
    @PostMapping("/selectOrder")
    public Result<IPage<TblOrder>> selectOrder(@RequestBody TblOrderRequest tblOrderRequest) {
        log.info("订单列表请求参数："+tblOrderRequest);

        IPage<TblOrder> tblOrderList = iTblOrderService.selectOrder(tblOrderRequest);

        return Result.success(tblOrderList);
    }

    /**
     * @description: 用户下单
     * @author: Lxk
     * @date: 2023/12/11 22:07
     * @param: [tblOrder]
     * @return: com.onLineCar.common.core.domain.Result<?>
     **/
    @PostMapping("/placeAnOrder")
    public Result<?> placeAnOrder(@RequestBody TblOrder tblOrder) {
        log.info("下单请求参数："+tblOrder);

        Result<TblOrder> tblOrderResult = this.selectByUserId(tblOrder.getPassengerInfoId());

        if (tblOrderResult.getData() != null){
            throw new RuntimeException("用户已下单,不能重复下单!");
        }

        String orderNumber = iTblOrderService.placeAnOrder(tblOrder);

        return Result.success(orderNumber,"下单成功!");
    }

    /**
     * @description: 司机接单
     * @author: Lxk
     * @date: 2023/12/18 8:49
     * @param: [tblOrder]
     * @return: com.onLineCar.common.core.domain.Result<?>
     **/
    @PostMapping("/driverTakeOrder")
    public Result<?> driverTakeOrder(@RequestBody TblOrder tblOrder) {
        log.info("司机接单请求参数："+tblOrder);

        Result<TblOrder> listResult = this.selectByDriverId(tblOrder.getDriverId());

        if (ObjectUtils.isNotEmpty(listResult.getData())){
            throw new RuntimeException("司机已接单,不能重复接单!");
       }

        int i = iTblOrderService.driverTakeOrder(tblOrder);

       if (0 == i){
           throw new RuntimeException("司机接单失败");
       }

       return Result.success(i,"司机接单成功!");
    }

    /**
     * @description: 司机redisson分布式锁抢单
     * @author: Lxk
     * @date: 2023/12/18 8:49
     * @param: reqDriverPreemptOrder
     * @return: com.onLineCar.common.core.domain.Result<?>
     **/
    @PostMapping("/redissonDriverPreempt")
    public Result redissonDriverPreempt(@RequestBody ReqDriverPreemptOrder reqDriverPreemptOrder) {
        log.info("功能名称:{司机redisson分布式锁抢单},请求参数:{}", reqDriverPreemptOrder);

        Result<TblOrder> listResult = this.selectByDriverId(reqDriverPreemptOrder.getDriverId());

        if (ObjectUtils.isNotEmpty(listResult.getData())){
            return Result.error("司机已接单,不能重复接单!");
        }

        boolean result = iTblOrderService.redissonDriverPreempt(reqDriverPreemptOrder);

        if (result) {
            return Result.success("抢单成功");
        } else {
            return Result.success("抢单失败");
        }
    }

    /**
     * @description: 查看订单详情
     * @author: Lxk
     * @date: 2023/12/13 18:54
     * @param: [tblOrder]
     * @return: com.onLineCar.common.core.domain.Result<com.onLine.vehicle.entity.TblOrder>
     **/
    @PostMapping("/selectOrderNumber")
    public Result<TblOrder> selectOrderNumber(@RequestBody TblOrder tblOrder)   {
        log.info("功能名称:查看订单详情,请求参数:{}",tblOrder);

        if (null == tblOrder.getOrderNumber()){
            throw new RuntimeException("订单号不能为空!");
        }

        TblOrder selectOrderNumber = iTblOrderService.selectOrderNumber(tblOrder.getOrderNumber());

        if (null == selectOrderNumber){
            throw new RuntimeException("订单不存在!");
        }

        return Result.success(selectOrderNumber);
    }

    @GetMapping("/selectOrderByOrderNum")
    public Result<TblOrder> selectOrderNumber(@RequestParam String orderNum)   {

        TblOrder selectOrderNumber = iTblOrderService.getById(orderNum);

        if (null == selectOrderNumber){
            throw new RuntimeException("订单不存在!");
        }

        return Result.success(selectOrderNumber);
    }

    /**
     * @description: 删除订单
     * @author: Lxk
     * @date: 2023/12/13 20:06
     * @param: [orderNumber]
     * @return: com.onLineCar.common.core.domain.Result<?>
     **/
    @DeleteMapping("/deleteOrderNumber/{orderNumber}")
    public Result<?> deleteOrderNumber(@NotBlank @PathVariable String orderNumber) {
        log.info("功能名称:删除订单,请求参数:{}",orderNumber);

        if (null == orderNumber){
            throw new RuntimeException("订单号不能为空!");
        }

        TblOrder selectOrderNumber = iTblOrderService.selectOrderNumber(orderNumber);
        if (null == selectOrderNumber ){
            throw new RuntimeException("订单不存在!");
        }

        if (0 == selectOrderNumber.getIsPaid()){
            throw new RuntimeException("订单还未支付，无法删除!");
        }

        int i = iTblOrderService.deleteOrderNumber(orderNumber);

        if (0 == i){
            throw new RuntimeException("删除失败");
        }

        return Result.success(i,"删除成功!");
    }

    /**
     * @description: 根据城市查询订单
     * @author: Lxk
     * @date: 2023/12/14 20:41
     * @param: [cityCode]
     * @return: com.onLineCar.common.core.domain.Result<java.util.List<com.onLine.vehicle.entity.TblOrder>>
     **/
    @GetMapping("/selectByCityCode/{cityCode}")
    public Result<List<TblOrder>> selectByCityCode(@PathVariable Long cityCode) {
        log.info("功能名称:根据城市查询订单,请求参数:{}",cityCode);

        if (null == cityCode){
            throw new RuntimeException("城市编码不能为空");
        }

        List<TblOrder> selectByCityCode = iTblOrderService.selectByCityCode(cityCode);

        if (null == selectByCityCode){
            throw new RuntimeException("订单不存在");
        }

        return Result.success(selectByCityCode);
    }

    // 司机端订单详情
    /**
     * @description: 根据司机id查询订单
     * @author: Lxk
     * @date: 2023/12/15 16:04
     * @param: [id]
     * @return: com.onLineCar.common.core.domain.Result<com.onLine.vehicle.entity.TblOrder>
     **/
    @GetMapping("/selectByDriverId/{driverId}")
    public Result<TblOrder> selectByDriverId(@PathVariable Integer driverId) {
        log.info("功能名称:根据司机id查询订单,请求参数:{}",driverId);

        if (null == driverId){
            throw new RuntimeException("司机id不能为空");
        }

        TblOrder tblOrder = iTblOrderService.selectByDriverId(driverId);

        return Result.success(tblOrder);
    }

    @PostMapping("/selectOrderByDriverId/{driverId}")
    public Result<List<TblOrder>> selectOrderByDriverId(@PathVariable Integer driverId){
        log.info("功能名称:根据司机id查询订单,请求参数:{}",driverId);
        if (null == driverId){
            throw new RuntimeException("司机id不能为空");
        }
        List<TblOrder> selectOrderByDriverId=iTblOrderService.selectOrderByDriverId(driverId);
        return Result.success(selectOrderByDriverId);
    }

    /**
     * @description: 司机查看自己的所有订单
     * @author: Lxk
     * @date: 2023/12/28 16:34
     * @param: [userOrderRequest]
     * @return: com.onLineCar.common.core.domain.Result<com.baomidou.mybatisplus.core.metadata.IPage<com.onLineCar.vehicle.entity.TblOrder>>
     **/
    @PostMapping("/selectAllByDriverId")
    public Result<IPage<TblOrder>> selectAllByUserId(@RequestBody DriverOrderRequest driverOrderRequest) {
        log.info("功能名称:根据用户id查询订单,请求参数:{}",driverOrderRequest);

        IPage<TblOrder> tblOrderList  = iTblOrderService.selectAllByDriverId(driverOrderRequest);

        return Result.success(tblOrderList );
    }

    // 用户端订单详情
    /**
     * @description: 根据用户id查询用户正在进行的订单
     * @author: Lxk
     * @date: 2023/12/15 15:41
     * @param: [id]
     * @return: com.onLineCar.common.core.domain.Result<com.onLine.vehicle.entity.TblOrder>
     **/
    @GetMapping("/selectByUserId/{id}")
    public Result<TblOrder> selectByUserId(@NotBlank @PathVariable Long id) {
        log.info("功能名称:根据用户id查询订单,请求参数:{}",id);

        if (null == id){
            throw new RuntimeException("用户id不能为空");
        }

        TblOrder tblOrder = iTblOrderService.selectByUserId(id);

        return Result.success(tblOrder);
    }

    /**
     * @description: 用户查看自己的所有订单
     * @author: Lxk
     * @date: 2023/12/15 19:46
     * @param: [id]
     * @return: com.onLineCar.common.core.domain.Result<com.onLine.vehicle.entity.TblOrder>
     **/
    @PostMapping("/selectAllByUserId")
    public Result<IPage<TblOrder>> selectAllByUserId(@RequestBody UserOrderRequest userOrderRequest) {
        log.info("功能名称:根据用户id查询订单,请求参数:{}",userOrderRequest);

        IPage<TblOrder> tblOrderList  = iTblOrderService.selectAllByUserId(userOrderRequest);

        return Result.success(tblOrderList );
    }

    /**
     * @description: 查询所有可接订单
     * @author: Lxk
     * @date: 2023/12/18 17:28
     * @param: [status]
     * @return: com.onLineCar.common.core.domain.Result<java.util.List<com.onLineCar.vehicle.entity.TblOrder>>
     **/
    @GetMapping("/selectAllByStatus")
    public Result<List<TblOrder>> selectAllByStatus() {
        log.info("功能名称:查询所有可接订单");

        List<TblOrder> tblOrder = iTblOrderService.selectList();

        return Result.success(tblOrder);
    }


    /**
     * @description: 根据订单编号查询当前城市的订单详情
     * @author: Lxk
     * @date: 2023/12/18 20:58
     * @param: [orderNumber]
     * @return: com.onLineCar.common.core.domain.Result<com.onLineCar.vehicle.entity.TblOrder>
     **/
    @GetMapping("/selectOrderByNumber/{orderNumber}")
    public Result<TblOrder> selectOrderByNumber(@NotBlank @PathVariable String orderNumber) {
        log.info("功能名称:查询订单详情,请求参数:{}",orderNumber);

        if (null == orderNumber){
            throw new RuntimeException("订单号不能为空!");
        }

        TblOrder selectOrderNumber = iTblOrderService.selectOrderNumber(orderNumber);
        // 优化下 查询不到订单很正常没必要抛异常，要抛异常也是调用方来抛
        return Result.success(selectOrderNumber);
    }

    /**
     * @description: 查询所有的已结束订单以及已取消订单
     * @author: Lxk
     * @date: 2023/12/18 18:42
     * @param: []
     * @return: com.onLineCar.common.core.domain.Result<java.util.List<com.onLineCar.vehicle.entity.TblOrder>>
     **/
    @GetMapping("/selectAllCloseOrder")
    public Result<List<TblOrder>> selectAllCloseOrder() {
        log.info("功能名称:查询所有已关闭订单");

        List<TblOrder> tblOrder = iTblOrderService.selectAllCloseOrder();

        return Result.success(tblOrder);
    }


    /**
     * @description: 根据订单编号修改订单状态
     * @param: requestUpdate
     */
    @PostMapping("/updateOrderStateByOrderNumber")
    public Result updateOrderStateByOrderNumber(@RequestBody RequestUpdate requestUpdate){
        log.info("功能名称:{根据订单编号修改订单状态},请求方法:{},请求URL:{},请求参数:{}",
                request.getMethod(), request.getRequestURL(), requestUpdate);
        iTblOrderService.updateOrderStateByOrderNumber(requestUpdate);
        log.info("功能名称:{根据订单编号修改订单状态},请求方法:{},请求URL:{}",
                request.getMethod(), request.getRequestURL());
        return Result.success();
    }

    /**
     * @description: 用户下单2,分库分表
     * @author: Lxk
     * @date: 2023/12/21 14:36
     * @param: [tblOrder]
     * @return: com.onLineCar.common.core.domain.Result
     **/
    @PostMapping("/userPlacesAnOrder")
    public Result userPlacesAnOrder(@RequestBody TblOrder tblOrder){
        log.info("下单请求参数："+tblOrder);

        Result<TblOrder> tblOrderResult = this.selectByUserId(tblOrder.getPassengerInfoId());

        if (tblOrderResult.getData() != null){
            throw new RuntimeException("用户有正在进行中的订单,不能重复下单!");
        }

        String orderNumber = iTblOrderService.userPlacesAnOrder(tblOrder);

        return Result.success(orderNumber,"下单成功!");
    }

    /**
     * @description: 用户取消订单
     * @author: Lxk
     * @date: 2023/12/25 17:06
     * @param: [reconciliation]
     * @return: com.onLineCar.common.core.domain.Result
     **/
    @PostMapping("/cancelOrder")
    public Result cancelOrder(@RequestBody Reconciliation reconciliation){
        if (ObjectUtils.isEmpty(reconciliation.getOrderNumber())){
            throw new RuntimeException("订单号不能为空!");
        }

        log.info("功能名称:{用户取消订单},请求方法:{},请求URL:{},请求参数:{}",
                request.getMethod(), request.getRequestURL(), JSON.toJSONString(reconciliation));

        iTblOrderService.cancelOrder(reconciliation);

        log.info("功能名称:{用户取消订单},请求方法:{},请求URL:{}",
                request.getMethod(), request.getRequestURL());

        return Result.success();
    }

    /**
     * @description: 疑义账单
     * @author: Lxk
     * @date: 2023/12/25 14:09
     * @param: [reconciliation]
     * @return: com.onLineCar.common.core.domain.Result
     **/
    @PostMapping("/updatebill")
    public Result updatebill(@RequestBody Reconciliation reconciliation){
        if (ObjectUtils.isEmpty(reconciliation.getOrderNumber())){
            throw new RuntimeException("订单号不能为空!");
        }

        log.info("功能名称:{疑义账单},请求方法:{},请求URL:{},请求参数:{}",
                request.getMethod(), request.getRequestURL(), reconciliation);

        iTblOrderService.updatebill(reconciliation);

        log.info("功能名称:{疑义账单},请求方法:{},请求URL:{}",
                request.getMethod(), request.getRequestURL());

        return Result.success();
    }

    /**
     * @description: 根据用户id查询订单
     * @author: Lxk
     * @date: 2023/12/18 8:50
     * @param: [tblOrder]
     * @return: int
     **/
    @GetMapping("/carryOut/{passengerInfoId}")
    public Result<TblOrder> carryOut(@PathVariable(value = "passengerInfoId") Integer passengerInfoId){
        log.info("功能名称:查询订单详情,请求参数:{}",passengerInfoId);
        if (null == passengerInfoId){
            throw new RuntimeException("用户id不能为空!");
        }
        TblOrder tblOrder = iTblOrderService.servletByInfoId(passengerInfoId);
        return Result.success(tblOrder);
    }

    /**
     * @description: 根据订单号修改状态
     * @author: Lxk
     * @date: 2023/12/30 10:44
     * @param: [orderNUmber]
     * @return: com.onLineCar.common.core.domain.Result
     **/
    @PostMapping ("/updateUserReach")
    @Transactional
    public Result updateUserReach(@RequestBody RequestUpdate requestUpdate){
        log.info("功能名称:{根据订单号修改状态},请求方法:{},请求URL:{},请求参数:{}",
                request.getMethod(), request.getRequestURL(), requestUpdate);

        if (StringUtils.isEmpty(requestUpdate.getOrderNumber())){
            throw new RuntimeException("订单号不能为空!");
        }
        return Result.success(iTblOrderService.updateUserReach(requestUpdate));
    }

}
